package com.twu.biblioteca;

import com.twu.biblioteca.commands.Command;
import com.twu.biblioteca.data_structures.Book;
import com.twu.biblioteca.data_structures.Library;
import com.twu.biblioteca.data_structures.Movie;
import com.twu.biblioteca.data_structures.User;

import java.io.PrintStream;

public class BibliotecaApp {
    private PrintStream ps;
    private Library library;
    private UserQueryHandler query;
    private State state;

    public BibliotecaApp(){
        this(System.out, new Library());
    }

    public BibliotecaApp(PrintStream ps, Library library)
    {
        this.ps = ps;
        this.library = library;
        constructDefaultLibrary();
        constructQuery();
        state = new StateWithoutUser(library, ps, query);
    }

    public static void main(String[] args) {
        new BibliotecaApp().run();
    }

    public void run(){
        printWelcome();
        do {
            updateState();
            printMenu();
            int commandNumber = query.userForInt("Please select an option: ");
            select(commandNumber);
            updateState();
        }while(true);
    }

    public void printWelcome(){
        ps.println("Welcome to the Biblioteca!");
    }

    public void printMenu(){
        int optionNumber=1;
        for(String menuItem : state.getMenu().keySet()){
            printMenuItem(optionNumber++, menuItem);
        }
    }

    public void select(int selection){
        int index = 1;
        for(Command command : state.getMenu().values())
            if(selection == index++)
            {
                command.run();
                return;
            }
        ps.println("Select a valid option!");
    }

    public void printMenuItem(int index, String menuItem){
        ps.print(index + ". ");
        ps.println(menuItem);
    }

    public void constructDefaultLibrary(){
        Book[] defaultListOfBooks =
             {
                 new Book("Crime and Punishment"),
                 new Book("The Brothers Karamazov"),
                 new Book("The Idiot"),
                 new Book("The Double"),
                 new Book("Anna Karenina")
             };
        library.add(defaultListOfBooks);

        Movie[] defaultListOfMovies =
             {
                 new Movie("Who's That Knocking at My Door","1967","Martin Scorsese",""),
                 new Movie("Taxi Driver", "1976", "Martin Scorsese", "8"),
                 new Movie("Raging Bull", "1980", "Martin Scorsese", "7"),
                 new Movie("After Hours", "1985", "Martin Scorsese", ""),
                 new Movie("Goodfellas", "1990", "Martin Scorsese", "8"),

                 new Movie("Cape Fear", "1991", "Martin Scorsese", "9"),
                 new Movie("Casino","1992","Martin Scorsese", "10"),
                 new Movie("The Aviator", "2004", "Martin Scorsese", "8"),
                 new Movie("The Departed", "2006", "Martin Scorsese", "10"),
                 new Movie("Shutter Island", "2010", "Martin Scorsese", "9"),

                 new Movie("The Anderson Tapes", "1971", "Sidney Lumet", ""),
                 new Movie("Serpico", "1973", "Sidney Lumet", "7"),
                 new Movie("Murder on the Orient Express", "1974", "Sidney Lumet", ""),
                 new Movie("Dog Day Afternoon", "1975", "Sidney Lumet", "10"),
                 new Movie("Prince of the City", "1981", "Sidney Lumet", "8"),
             };
        library.add(defaultListOfMovies);

        User[] defaultListOfUsers = {
                new User("111-1111", "admin", "Administrator", "(555) 555-5555", "admin@gmail.com"),
                new User("111-1112", "guest", "Oliver Connors", "(246) 573-4611", "olconnors78@gmail.com"),
                new User("111-1113", "password7", "Jeremy Fisher", "(246) 414-1496", "jfisher7@gmail.com")
        };
        library.add(defaultListOfUsers);
    }

    public void constructQuery(){
        query = new UserQueryHandler(ps, System.in);
    }

    public void updateState(){
        User user = library.getActiveUser();
        if(user!=null)
            state = new StateWithUser(library,ps,query,user);
    }

}
